package com.train.base.service.impl;

import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SnowflakeIdWorker;
import com.ruoyi.common.utils.StringUtils;
import com.train.base.domain.ExamQuestionBank;
import com.train.base.domain.ExamTestPaperExtractRule;
import com.train.base.domain.ExamTestPaperModule;
import com.train.base.domain.ExamTestPaperRequired;
import com.train.base.entity.bo.Question;
import com.train.base.enums.TestPaperTypeEnums;
import com.train.base.mapper.ExamTestPaperModuleMapper;
import com.train.base.service.IExamQuestionBankService;
import com.train.base.service.IExamTestPaperModuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 试卷模板Service业务层处理
 *
 * @author keke
 * @date 2024-03-28
 */
@Service
public class ExamTestPaperModuleServiceImpl implements IExamTestPaperModuleService {
    @Autowired
    private ExamTestPaperModuleMapper examTestPaperModuleMapper;
    @Autowired
    private IExamQuestionBankService iExamQuestionBankService;

    /**
     * 查询试卷模板
     *
     * @param id 试卷模板主键
     * @return 试卷模板
     */
    @Override
    public ExamTestPaperModule selectExamTestPaperModuleById(Long id) {
        ExamTestPaperModule examTestPaperModule = examTestPaperModuleMapper.selectExamTestPaperModuleById(id);
        if(Objects.isNull(examTestPaperModule)){
            throw new BaseException("请先维护试卷生成模板");
        }
        // 查询题库信息
        List<Long> questIds = examTestPaperModule.getExamTestPaperRequired().stream().map(ExamTestPaperRequired::getQuestionId).toList();
        Map<Long, ExamQuestionBank> questionBankMap = iExamQuestionBankService.selectExamQuestionBankByIds(questIds).stream().collect(Collectors.toMap(ExamQuestionBank::getId, b -> b));
        examTestPaperModule.getExamTestPaperRequired().forEach(module -> {
            ExamQuestionBank bank = questionBankMap.get(module.getQuestionId());
            module.setCode(bank.getCode());
            module.setDeptId(bank.getDeptId());
            module.setSyllabusCode(bank.getSyllabusCode());
            module.setPostId(bank.getPostId());
            module.setPostLevelCode(bank.getPostLevelCode());
            module.setSubjectName(bank.getSubjectName());
            module.setKnowledgePointsName(bank.getKnowledgePointsName());
            module.setQuestionType(bank.getQuestionType());
            module.setContent(bank.getContent());
        });
        return examTestPaperModule;
    }

    /**
     * 查询试卷模板列表
     *
     * @param examTestPaperModule 试卷模板
     * @return 试卷模板
     */
    @Override
    public List<ExamTestPaperModule> selectExamTestPaperModuleList(ExamTestPaperModule examTestPaperModule) {
        return examTestPaperModuleMapper.selectExamTestPaperModuleList(examTestPaperModule);
    }

    /**
     * 新增试卷模板
     *
     * @param examTestPaperModule 试卷模板
     * @return 结果
     */
    @Transactional
    @Override
    public int insertExamTestPaperModule(ExamTestPaperModule examTestPaperModule) {

        examTestPaperModule.setCreateTime(LocalDateTime.now());
        examTestPaperModule.setId(SnowflakeIdWorker.build().nextId());
        int rows = examTestPaperModuleMapper.insertExamTestPaperModule(examTestPaperModule);
        insertExamTestPaperExtractRule(examTestPaperModule);
        insertExamTestPaperRequired(examTestPaperModule);
        return rows;
    }


    /**
     * 修改试卷模板
     *
     * @param examTestPaperModule 试卷模板
     * @return 结果
     */
    @Transactional
    @Override
    public int updateExamTestPaperModule(ExamTestPaperModule examTestPaperModule) {
        examTestPaperModule.setUpdateTime(DateUtils.getNowDate());
        examTestPaperModuleMapper.deleteExamTestPaperExtractRuleByExamTestPaperModuleId(examTestPaperModule.getId());
        examTestPaperModuleMapper.deleteExamTestPaperRequiredByExamTestPaperModuleId(examTestPaperModule.getId());
        insertExamTestPaperExtractRule(examTestPaperModule);
        insertExamTestPaperRequired(examTestPaperModule);
        return examTestPaperModuleMapper.updateExamTestPaperModule(examTestPaperModule);
    }

    /**
     * 批量删除试卷模板
     *
     * @param ids 需要删除的试卷模板主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteExamTestPaperModuleByIds(Long[] ids) {
        examTestPaperModuleMapper.deleteExamTestPaperExtractRuleByExamTestPaperModuleIds(ids);
        examTestPaperModuleMapper.deleteExamTestPaperRequiredByExamTestPaperModuleIds(ids);
        return examTestPaperModuleMapper.deleteExamTestPaperModuleByIds(ids);
    }

    /**
     * 删除试卷模板信息
     *
     * @param id 试卷模板主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteExamTestPaperModuleById(Long id) {
        examTestPaperModuleMapper.deleteExamTestPaperExtractRuleByExamTestPaperModuleId(id);
        examTestPaperModuleMapper.deleteExamTestPaperRequiredByExamTestPaperModuleId(id);
        return examTestPaperModuleMapper.deleteExamTestPaperModuleById(id);
    }

    @Override
    public List<Question> createPaper(ExamTestPaperModule examTestPaperModule) {
        List<Question> questions = new ArrayList<>();
        // 处理固定题目
        List<ExamTestPaperRequired> examTestPaperRequired = examTestPaperModule.getExamTestPaperRequired();
        examTestPaperRequired.forEach(e -> {
            Question question = new Question();
            question.setQuestionId(e.getQuestionId());
            question.setGrade(e.getGrade());
            questions.add(question);
        });
        if (!questions.isEmpty()) {
            List<Long> bankIds = questions.stream().map(Question::getQuestionId).toList();
            List<ExamQuestionBank> banks = iExamQuestionBankService.selectExamQuestionBankByIds(bankIds);
            Map<Long, ExamQuestionBank> mapBanks = banks.stream().collect(Collectors.toMap(ExamQuestionBank::getId, Function.identity()));
            questions.forEach(q -> {
                ExamQuestionBank bank = mapBanks.get(q.getQuestionId());
                if (Objects.nonNull(bank)) {
                    q.setType(bank.getQuestionType());
                    q.setExamQuestionBankOptionList(bank.getExamQuestionBankOptionList());
                    q.setContent(bank.getContent());
                    q.setRightKey(bank.getRightKey());
                }
            });
        }
        if (examTestPaperModule.getType().equals(TestPaperTypeEnums.RANDOM.getCode())) {
            // 处理抽取题目
            List<ExamTestPaperExtractRule> rules = examTestPaperModule.getExamTestPaperExtractRuleList();
            rules.forEach(e -> {
                e.setNumber(e.getNumber());
                List<ExamQuestionBank> banks = iExamQuestionBankService.selecRandByRule(e);
                banks.forEach(b -> {
                    // 如果题目已经存在
                    if(questions.stream().map(Question::getQuestionId).toList().contains(b.getId())){
                        return;
                    }
                    Question question = new Question();
                    question.setQuestionId(b.getId());
                    question.setGrade(e.getGrade());
                    question.setAnalysis(b.getAnalysis());
                    question.setContent(b.getContent());
                    question.setRightKey(b.getRightKey());
                    question.setExamQuestionBankOptionList(b.getExamQuestionBankOptionList());
                    questions.add(question);
                });
            });
        }
        return questions;
    }

    @Override
    public List<ExamTestPaperModule> selectExamTestPaperModuleByIds(List<Long> moduleIds) {
        if(CollectionUtils.isEmpty(moduleIds)){
            return Collections.emptyList();
        }
        return examTestPaperModuleMapper.selectExamTestPaperModuleByIds(moduleIds);
    }

    @Override
    public ExamTestPaperModule getByName(String name) {
        return examTestPaperModuleMapper.getByName(name);
    }

    /**
     * 新增试卷试题抽取规则信息
     *
     * @param examTestPaperModule 试卷模板对象
     */
    public void insertExamTestPaperExtractRule(ExamTestPaperModule examTestPaperModule) {
        List<ExamTestPaperExtractRule> examTestPaperExtractRuleList = examTestPaperModule.getExamTestPaperExtractRuleList();
        Long id = examTestPaperModule.getId();
        if (StringUtils.isNotNull(examTestPaperExtractRuleList)) {
            List<ExamTestPaperExtractRule> list = new ArrayList<ExamTestPaperExtractRule>();
            for (int i = 0; i < examTestPaperExtractRuleList.size(); i++) {
                ExamTestPaperExtractRule examTestPaperExtractRule = examTestPaperExtractRuleList.get(i);
                //校验规则是否成功
                ExamQuestionBank examQuestionBank = new ExamQuestionBank();
                examQuestionBank.setQuestionType(examTestPaperExtractRule.getQuestionType());
                examQuestionBank.setDeptId(examTestPaperModule.getDeptId());
                examQuestionBank.setSyllabusCode(examTestPaperExtractRule.getSyllabusCode());
                examQuestionBank.setPostId(examTestPaperModule.getPostId());
                examQuestionBank.setPostLevelCode(examTestPaperExtractRule.getPostLevelCode());
                examQuestionBank.setSubjectId(examTestPaperExtractRule.getSubjectId());
                examQuestionBank.setKnowledgePointsId(examTestPaperExtractRule.getKnowledgePointId());
                List<ExamQuestionBank> examQuestionBanks = iExamQuestionBankService.selectExamQuestionBankList(examQuestionBank);
                if (examQuestionBanks.size() < examTestPaperExtractRule.getNumber()) {
                    throw new BaseException("第" + i + "规则配置失败，因为题库不足");
                }

                examTestPaperExtractRule.setId(SnowflakeIdWorker.build().nextId());
                examTestPaperExtractRule.setExamTestPaperModuleId(id);
                examTestPaperExtractRule.setDeptId(examTestPaperModule.getDeptId());
                examTestPaperExtractRule.setPostId(examTestPaperModule.getPostId());
                examTestPaperExtractRule.setPostLevelCode(examTestPaperExtractRule.getPostLevelCode());
                list.add(examTestPaperExtractRule);
            }
            if (!list.isEmpty()) {
                examTestPaperModuleMapper.batchExamTestPaperExtractRule(list);
            }
        }
    }

    /**
     * 新增试卷模板中的固定题
     *
     * @param examTestPaperModule
     */
    private void insertExamTestPaperRequired(ExamTestPaperModule examTestPaperModule) {
        List<ExamTestPaperRequired> examTestPaperRequireds = examTestPaperModule.getExamTestPaperRequired();
        Long id = examTestPaperModule.getId();
        if (!CollectionUtils.isEmpty(examTestPaperRequireds)) {
            List<ExamTestPaperRequired> list = new ArrayList<ExamTestPaperRequired>();
            for (ExamTestPaperRequired examTestPaperRequired : examTestPaperRequireds) {
                examTestPaperRequired.setId(SnowflakeIdWorker.build().nextId());
                examTestPaperRequired.setExamTestPaperModuleId(id);
                list.add(examTestPaperRequired);
            }
            if (list.size() > 0) {
                examTestPaperModuleMapper.batchExamTestPaperRequired(list);
            }
        }
    }
}
